package com.gr3g.dev.learndraw.util;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.content.res.AssetManager;
import android.util.JsonReader;
import android.util.Log;

import com.gr3g.dev.learndraw.model.Categorie;
import com.gr3g.dev.learndraw.model.Dessin;
import com.gr3g.dev.learndraw.model.Etape;
import com.gr3g.dev.learndraw.model.IPath;
import com.gr3g.dev.learndraw.model.draw.Arc;
import com.gr3g.dev.learndraw.model.draw.Circle;
import com.gr3g.dev.learndraw.model.draw.Line;

/** @author Gregory Tardivel */
public final class ModelesLoader {

    public static List<Categorie> process(final Context context) {
        final List<Categorie> retour = new ArrayList<Categorie>();
        final AssetManager manager = context.getAssets();
        try {
            final InputStream modeles = manager.open("modeles.json");
            final InputStreamReader inReader = new InputStreamReader(modeles);
            retour.addAll(load(inReader));
        } catch (final IOException exc) {
            Log.e("ModelesLoader", "Erreur de chargement des modeles", exc);
        }
        return retour;
    }

    public static List<Categorie> load(final InputStreamReader inReader)
            throws IOException {
        final List<Categorie> retour = new ArrayList<Categorie>();
        final JsonReader json = new JsonReader(inReader);
        json.setLenient(true);
        // {
        json.beginObject();
        // dessins:
        final String modeles = json.nextName();
        if ("modeles".equals(modeles)) {
            // [
            json.beginArray();
            while (json.hasNext()) {
                retour.add(loadModeles(json));
            }
            // ]
            json.endArray();
        }
        // }
        json.endObject();
        json.close();
        inReader.close();
        return retour;
    }

    private static Categorie loadModeles(final JsonReader json)
            throws IOException {
        final Categorie categorie = new Categorie();
        // {
        json.beginObject();
        // type:
        final String type = json.nextName();
        if ("type".equals(type)) {
            // value,
            categorie.setTitre(json.nextString());
        }
        // dessins
        final String dessins = json.nextName();
        if ("dessins".equals(dessins)) {
            // [
            json.beginArray();
            while (json.hasNext()) {
                categorie.addDessin(loadDessin(json));
            }
            // ]
            json.endArray();
        }
        // }
        json.endObject();
        return categorie;
    }

    private static Dessin loadDessin(final JsonReader json)
            throws IOException {
        final Dessin dessin = new Dessin();
        // {
        json.beginObject();
        // name:
        final String name = json.nextName();
        if ("name".equals(name)) {
            // value,
            dessin.setName(json.nextString());
        }
        // etapes:
        final String etapes = json.nextName();
        if ("etapes".equals(etapes)) {
            // [
            json.beginArray();
            while (json.hasNext()) {
                dessin.addEtape(loadEtape(json));
            }
            // ]
            json.endArray();
        }
        // }
        json.endObject();
        return dessin;
    }

    private static IPath loadPath(final JsonReader json)
            throws IOException {
        IPath path = null;
        // {
        json.beginObject();
        final String type = json.nextName();
        if ("line".equals(type)) {
            // line:
            path = loadLine(json);
        } else if ("circle".equals(type)) {
            // circle:
            path = loadCircle(json);
        } else if ("arc".equals(type)) {
            // arc:
            path = loadArc(json);
        }
        // }
        json.endObject();
        return path;
    }

    private static Etape loadEtape(final JsonReader json)
            throws IOException {
        final Etape etape = new Etape();
        // {
        json.beginObject();
        final String paths = json.nextName();
        if ("paths".equals(paths)) {
            // [
            json.beginArray();
            while (json.hasNext()) {
                etape.addPath(loadPath(json));
            }
            // ]
            json.endArray();
        }
        // }
        json.endObject();
        return etape;
    }

    private static Line loadLine(final JsonReader json)
            throws IOException {
        final Line line = new Line();
        // {
        json.beginObject();
        while (json.hasNext()) {
            final String attr = json.nextName();
            final int value = json.nextInt();
            if ("x1".equals(attr)) {
                // x1: value,
                line.setX1(value);
            } else if ("x2".equals(attr)) {
                // x2: value,
                line.setX2(value);
            } else if ("y1".equals(attr)) {
                // y1: value,
                line.setY1(value);
            } else if ("y2".equals(attr)) {
                // y1: value
                line.setY2(value);
            }
        }
        // }
        json.endObject();
        return line;
    }

    private static Circle loadCircle(final JsonReader json)
            throws IOException {
        final Circle circle = new Circle();
        // {
        json.beginObject();
        while (json.hasNext()) {
            final String attr = json.nextName();
            final int value = json.nextInt();
            if ("x".equals(attr)) {
                // x: value,
                circle.setX(value);
            } else if ("y".equals(attr)) {
                // y: value,
                circle.setY(value);
            } else if ("radius".equals(attr)) {
                // radius: value,
                circle.setRadius(value);
            } else if ("filled".equals(attr)) {
                // filled: value,
                circle.setFilled(value == 1);
            }
        }
        // }
        json.endObject();
        return circle;
    }

    private static Arc loadArc(final JsonReader json)
            throws IOException {
        final Arc arc = new Arc();
        // {
        json.beginObject();
        while (json.hasNext()) {
            final String attr = json.nextName();
            final int value = json.nextInt();
            if ("left".equals(attr)) {
                // left: value,
                arc.setLeft(value);
            } else if ("top".equals(attr)) {
                // top: value,
                arc.setTop(value);
            } else if ("right".equals(attr)) {
                // right: value,
                arc.setRight(value);
            } else if ("bottom".equals(attr)) {
                // bottom: value,
                arc.setBottom(value);
            } else if ("startAngle".equals(attr)) {
                // startAngle: value,
                arc.setStartAngle(value);
            } else if ("sweepAngle".equals(attr)) {
                // sweepAngle: value,
                arc.setSweepAngle(value);
            } else if ("filled".equals(attr)) {
                // filled: value,
                arc.setFilled(value == 1);
            }
        }
        // }
        json.endObject();
        return arc;
    }
}
